#include <sys/syscall.h>
#include <mips/regdef.h>

	.text
	.align 	2
	.global mergesort
	.ent 	mergesort

mergesort:
	.frame	$fp,40,ra

	.set noreorder
	.cpload	t9
	.set reorder

	subu	sp,sp,40

	# Guardo los registros
	.cprestore 24
	sw	ra,32(sp)
	sw	$fp,28(sp)
	move	$fp,sp

	# Guardo los parametros
	sw	a0, 40($fp) // cadena a ordenar
	sw	a1, 44($fp) // buffer resultado
	
	# llamo a la funcion length:
	lw		a0, 40($fp)
	jal		length
	sw      v0, 16($fp)
	
	# imprimero la cadena input
	li	v0, SYS_write 
	li	a0, 1
	lw	a1, 40($fp)
	lw	a2, 16($fp)
	syscall
	
	# imprimo un salto de linea
	li	v0, SYS_write 
	li	a0, 1
	la	a1, str_salto
	li	a2, 1
	syscall
	
	# Si la cadena de entrada tiene longitud igual o menor
	# a uno, entonces termina.
	lw	t0, 16($fp)
	li	t1, 2
	beq t0, t1, terminar_merge_sort
	
	# sino
	# obtengo la parte izquierda
	li	t1, 2
	div	t2, t0, t1
	sw	t2, 20($fp)
	
	# en t2 tengo el tamanio de los vectores a malloquear
	# malloc
	lw		a0,	20($fp)
	addiu	a0, a0, 1
	jal 	mymalloc
	sw      v0, 16($fp)
	
	# copio los primeros n chars del string original al malloqueado
	# cargo el buffer con los primeros chars
	li		t1, 0
	lw		t2, 16($fp) // ptr a leftStr
	lw		t0, 40($fp) // ptr a originStr
	lw		t3,	20($fp) // length
	
while_loop:
	beq	t1, t3 ,invocacion_recursiva
	lb	t4,	0(t0)
	sb	t4, 0(t2)
	addiu	t1, t1, 1 // i++
	addiu	t0, t0, 1
	addiu	t2, t2, 1	
	j 	while_loop

invocacion_recursiva:
	# vuelvo a llamar a mergesort con left
	lw	a0, 16($fp)
	li	a1, 0
	jal	mergesort
	sw      v0, 20($fp)
	
	# free del buffer
	lw		a0,	16($fp)
	jal 	myfree

	
terminar_merge_sort:
	# Imprimo el resultado por pantalla
	li	v0, SYS_write 
	li	a0, 1
	la	a1, str_esmenorauno
	li	a2, 16
	syscall	
	
	# destruyo el stack
	move	sp, $fp
	lw	$fp, 28(sp)
	lw	ra,  32(sp)
	addu	sp, sp, 40

	j	ra
	.end	mergesort
	
	.rdata
str_esmenorauno: .asciiz	"Es menor a uno.\n"
str_nomenorauno: .asciiz	"No menor a uno.\n"
str_salto: .asciiz	"\n"
